package com.wonderful.compose.clock

import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableLongStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.wonderful.compose.R
import java.util.Calendar
import java.util.TimeZone

/**
 * Desc:
 * @Author: wonderful
 * @Time: 2023/11/16 15:10
 */

@Composable
fun ImageClock() {
    // 实现时间的转换
    val calendar = remember {
        Calendar.getInstance()
    }
    // 触发 UI 的刷新
    val curTime = remember {
        mutableLongStateOf(System.currentTimeMillis())
    }
    val resIds = rememberResourceIds(calendar = calendar, curTime = curTime)

    val receiver = rememberBroadcastReceiver(calendar = calendar, curTime = curTime)

    val context = LocalContext.current

    DisposableEffect(Unit) {
        val filter = IntentFilter().apply {
            addAction(Intent.ACTION_TIME_TICK)
            addAction(Intent.ACTION_TIME_CHANGED)
            addAction(Intent.ACTION_TIMEZONE_CHANGED)
        }
        context.registerReceiver(receiver, filter)
        onDispose { // 取消广播注册
            context.unregisterReceiver(receiver)
        }
    }

    Column(modifier = Modifier.padding(20.dp)) {
        Row {
            Image(
                painter = painterResource(id = resIds.hourTensResId),
                contentDescription = "hourTensImg"
            )
            Image(
                painter = painterResource(id = resIds.hourUnitsResId),
                contentDescription = "hourUnitsImg"
            )
        }
        Row {
            Image(
                painter = painterResource(id = resIds.minTensResId),
                contentDescription = "minTensImg"
            )
            Image(
                painter = painterResource(id = resIds.minUnitsResInt),
                contentDescription = "minUnitsImg"
            )
        }
    }

}

@Composable
private fun rememberBroadcastReceiver(calendar: Calendar, curTime: MutableState<Long>) = remember {
    object : BroadcastReceiver() {
        override fun onReceive(context: Context?, intent: Intent?) {
            if (Intent.ACTION_TIMEZONE_CHANGED == intent?.action) {
                val timeZone = TimeZone.getTimeZone(intent.getStringExtra(Intent.EXTRA_TIMEZONE))
                calendar.timeZone = timeZone
            }

            // update time
            curTime.value = System.currentTimeMillis()
            calendar.timeInMillis = curTime.value
        }

    }
}

@Composable
private fun rememberResourceIds(calendar: Calendar, curTime: MutableState<Long>): TimeResourceIds {
    val hourTensResId by remember(curTime.value) {
        derivedStateOf { getResourceId(calendar.get(Calendar.HOUR_OF_DAY) / 10) }
    }
    val hourUnitsResId by remember(curTime.value) {
        derivedStateOf { getResourceId(calendar.get(Calendar.HOUR_OF_DAY) % 10) }
    }
    val minTensResId by remember(curTime.value) {
        derivedStateOf { getResourceId(calendar.get(Calendar.MINUTE) / 10) }
    }
    val minUnitsResInt by remember(curTime.value) {
        derivedStateOf { getResourceId(calendar.get(Calendar.MINUTE) % 10) }
    }
    return TimeResourceIds(hourTensResId, hourUnitsResId, minTensResId, minUnitsResInt)
}

fun getResourceId(num: Int) = when (num) {
    0 -> R.drawable.clock_num_0
    1 -> R.drawable.clock_num_1
    2 -> R.drawable.clock_num_2
    3 -> R.drawable.clock_num_3
    4 -> R.drawable.clock_num_4
    5 -> R.drawable.clock_num_5
    6 -> R.drawable.clock_num_6
    7 -> R.drawable.clock_num_7
    8 -> R.drawable.clock_num_8
    9 -> R.drawable.clock_num_9
    else -> R.drawable.clock_num_0
}

data class TimeResourceIds(
    val hourTensResId: Int,
    val hourUnitsResId: Int,
    val minTensResId: Int,
    val minUnitsResInt: Int
)

@Preview
@Composable
fun ImageClockPreview() {
    ImageClock()
}